package com.key.win.business.chat.service.impl;

import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.key.win.base.auth.AuthenticationUtil;
import com.key.win.base.page.MybatisOderByVo;
import com.key.win.base.page.MybatisPageServiceTemplate;
import com.key.win.base.web.OrderDir;
import com.key.win.base.web.PageRequest;
import com.key.win.base.web.PageResult;
import com.key.win.business.chat.dao.ImMessageDetailDao;
import com.key.win.business.chat.dao.ImMessageFullDao;
import com.key.win.business.chat.dao.ImMessageNumDao;
import com.key.win.business.chat.eums.ImMessageContentTypeEnum;
import com.key.win.business.chat.eums.ImMessageTargetEnum;
import com.key.win.business.chat.model.ImMessageDetail;
import com.key.win.business.chat.service.ImMessageDetailService;
import com.key.win.business.chat.vo.ImMessageFullVo;
import com.key.win.business.chat.vo.ImMessageNumVo;
import com.key.win.business.chat.vo.ImSystemMessageFullVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

@Service
public class ImMessageDetailServiceImpl extends ServiceImpl<ImMessageDetailDao, ImMessageDetail> implements ImMessageDetailService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private ImMessageFullDao imMessageFullDao;

    @Autowired
    private ImMessageNumDao imMessageNumDao;

    public PageResult<ImMessageDetail> findMessageDetailByPaged(PageRequest<ImMessageDetail> t) {
        MybatisPageServiceTemplate<ImMessageDetail, ImMessageDetail> query = new MybatisPageServiceTemplate<ImMessageDetail, ImMessageDetail>(this.baseMapper) {
            @Override
            protected AbstractWrapper constructWrapper(ImMessageDetail message) {
                LambdaQueryWrapper<ImMessageDetail> lambdaQueryWrapper = buildWrapper(message);
                return lambdaQueryWrapper;
            }
        };
        return query.doPagingQuery(t);
    }

    @Override
    public PageResult<ImMessageFullVo> findMessageFullByPaged(PageRequest<ImMessageFullVo> t) {
        MybatisPageServiceTemplate<ImMessageFullVo, ImMessageFullVo> query = new MybatisPageServiceTemplate<ImMessageFullVo, ImMessageFullVo>(this.imMessageFullDao) {
            @Override
            protected AbstractWrapper constructWrapper(ImMessageFullVo imMessageFullVo) {
                if (imMessageFullVo == null) {
                    logger.error("ImMessageDetail is null!!");
                    throw new IllegalArgumentException("查询条件为空！");
                }
                if (imMessageFullVo.getTarget() == null) {
                    logger.error("ImMessageDetail target is null!!");
                    throw new IllegalArgumentException("目标条件为空！");
                }
                if (StringUtils.isBlank(imMessageFullVo.getTargetId())) {
                    logger.error("ImMessageDetail targetId is null!!");
                    throw new IllegalArgumentException("目标Id条件为空！");
                }
                LambdaQueryWrapper<ImMessageFullVo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(ImMessageDetail::getTarget, imMessageFullVo.getTarget());
                if (ImMessageTargetEnum.FRIEND == imMessageFullVo.getTarget()) {
                    lambdaQueryWrapper.and(qw ->
                            qw.and(q ->
                                    q.eq(ImMessageFullVo::getFromUserId, imMessageFullVo.getFromUserId())
                                            .eq(ImMessageFullVo::getToUserId, imMessageFullVo.getToUserId())
                            ).or(q ->
                                    q.eq(ImMessageFullVo::getFromUserId, imMessageFullVo.getToUserId())
                                            .eq(ImMessageFullVo::getToUserId, imMessageFullVo.getFromUserId())
                            )
                    );
                } else {
                    if (StringUtils.isNotBlank(imMessageFullVo.getFromUserId())) {
                        lambdaQueryWrapper.eq(ImMessageFullVo::getFromUserId, imMessageFullVo.getFromUserId());
                    }
                    if (StringUtils.isNotBlank(imMessageFullVo.getToUserId())) {
                        lambdaQueryWrapper.eq(ImMessageFullVo::getToUserId, imMessageFullVo.getToUserId());
                    }
                }
                if (imMessageFullVo.getStatus() != null) {
                    lambdaQueryWrapper.eq(ImMessageFullVo::getStatus, imMessageFullVo.getStatus());
                }
                if (StringUtils.isNotBlank(imMessageFullVo.getContent())) {
                    lambdaQueryWrapper.like(ImMessageFullVo::getContent, imMessageFullVo.getContent());
                }
                if (imMessageFullVo.getTarget() == ImMessageTargetEnum.GROUP) {
                    lambdaQueryWrapper.eq(ImMessageDetail::getTargetId, imMessageFullVo.getTargetId());
                }
                if (imMessageFullVo.getCreateDate() != null) {
                    lambdaQueryWrapper.lt(ImMessageFullVo::getCreateDate, imMessageFullVo.getCreateDate());
                }
                String messageContentTypeStr = imMessageFullVo.getMessageContentType();
                if (StringUtils.isNotBlank(messageContentTypeStr)) {
                    List<ImMessageContentTypeEnum> collection = ImMessageContentTypeEnum.getImMessageContentTypeEnums(messageContentTypeStr);
                    if (!CollectionUtils.isEmpty(collection)) {
                        lambdaQueryWrapper.in(ImMessageFullVo::getContentType, collection);
                    }
                }

                return lambdaQueryWrapper;
            }

            @Override
            protected String constructNativeSql() {
                return "SELECT * FROM (SELECT a.*, b.content,b.content_type,CASE a.target WHEN 0 THEN ( CASE WHEN f.`name` IS NOT NULL THEN f.`name` ELSE u.nick_name END ) WHEN 1 THEN ( CASE WHEN gu.`name` IS NOT NULL THEN gu.`name` ELSE u.nick_name END ) ELSE u.nick_name END AS nick_name FROM im_message_detail a INNER JOIN im_message b ON a.message_id = b.id  INNER JOIN sys_user u ON b.from_user_id = u.id LEFT JOIN im_group g ON g.id = a.target_Id LEFT JOIN im_group_user gu ON gu.group_Id = g.id AND gu.user_Id = a.from_User_Id LEFT JOIN im_friends f ON f.friend_Id = a.from_User_Id AND f.user_Id = a.to_User_Id ) IM_MESSAGE_FULL";
            }

            @Override
            protected List<MybatisOderByVo> getQueryOrder(PageRequest<ImMessageFullVo> pageParam) {
                List<MybatisOderByVo> mybatisOderByVos = new ArrayList<>();
                MybatisOderByVo mybatisOderByVo = new MybatisOderByVo();
                mybatisOderByVo.setSortName("createDate");
                mybatisOderByVo.setSortDir(OrderDir.DESC);
                mybatisOderByVos.add(mybatisOderByVo);
                return mybatisOderByVos;
            }
        };
        return query.doPagingQuery(t);
    }

    private LambdaQueryWrapper<ImMessageDetail> buildWrapper(ImMessageDetail imMessageDetail) {
        if (imMessageDetail == null) {
            logger.error("ImMessageDetail is null!!");
            throw new IllegalArgumentException("查询条件为空！");
        }
        if (imMessageDetail.getTarget() == null) {
            logger.error("ImMessageDetail target is null!!");
            throw new IllegalArgumentException("目标条件为空！");
        }
        LambdaQueryWrapper<ImMessageDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ImMessageDetail::getTarget, imMessageDetail.getTarget());
        if (StringUtils.isNotBlank(imMessageDetail.getFromUserId())) {
            lambdaQueryWrapper.like(ImMessageDetail::getFromUserId, imMessageDetail.getFromUserId());
        }
        if (StringUtils.isNotBlank(imMessageDetail.getToUserId())) {
            lambdaQueryWrapper.like(ImMessageDetail::getToUserId, imMessageDetail.getToUserId());
        }
        if (imMessageDetail.getStatus() != null) {
            lambdaQueryWrapper.eq(ImMessageDetail::getStatus, imMessageDetail.getStatus());
        }
        return lambdaQueryWrapper;
    }

    public List<ImMessageDetail> findMessageDetail(ImMessageDetail ImMessageDetail) {
        return this.list(this.buildWrapper(ImMessageDetail));
    }

    public boolean addMessageDetail(ImMessageDetail imMessageDetail) {
        if (imMessageDetail == null) {
            logger.error("ImMessageDetail is null!!");
            throw new IllegalArgumentException("消息为空！");
        }
        if (StringUtils.isBlank(imMessageDetail.getFromUserId())) {
            logger.error("ImMessageDetail fromUserId is null!!");
            throw new IllegalArgumentException("发送人为空！");
        }
        if (imMessageDetail.getTarget() == null) {
            logger.error("ImMessageDetail target is null!!");
            throw new IllegalArgumentException("消息目标为空！");
        }
        if (imMessageDetail.getType() == null) {
            logger.error("ImMessageDetail type is null!!");
            throw new IllegalArgumentException("消息类型为空！");
        }
        // imMessageDetail.setStatus(Boolean.FALSE);
        return this.save(imMessageDetail);
    }

    @Override
    public boolean updateMessageByStatus(ImMessageDetail imMessageDetail) {
        if (imMessageDetail == null) {
            logger.error("ImMessageDetail is null!!");
            throw new IllegalArgumentException("消息为空！");
        }
        if (StringUtils.isBlank(imMessageDetail.getId())) {
            logger.error("ImMessageDetail is null!!");
            throw new IllegalArgumentException("消息Id为空！");
        }
        ImMessageDetail byId = this.getById(imMessageDetail.getId());
        if (imMessageDetail == null) {
            logger.error("ImMessageDetail is null!!");
            throw new IllegalArgumentException("消息不存在！");
        }
        byId.setStatus(Boolean.TRUE);
        return saveOrUpdate(byId);
    }

    @Override
    public boolean updateMessageStatusByBatch(ImMessageDetail imMessageDetail) {
        if (imMessageDetail == null) {
            logger.error("ImMessageDetail is null!!");
            throw new IllegalArgumentException("消息为空！");
        }
        if (imMessageDetail.getTarget() == null) {
            logger.error("ImMessageDetail target is null!!");
            throw new IllegalArgumentException("消息目标为空！");
        }
        if (imMessageDetail.getType() == null) {
            logger.error("ImMessageDetail type is null!!");
            throw new IllegalArgumentException("消息类型为空！");
        }
        if (StringUtils.isBlank(imMessageDetail.getToUserId())) {
            logger.error("ImMessageDetail toUserId is null!!");
            throw new IllegalArgumentException("接收人为空！");
        }
        if (StringUtils.isBlank(imMessageDetail.getTargetId())) {
            logger.error("ImMessageDetail targetId is null!!");
            throw new IllegalArgumentException("目标Id人为空！");
        }

        LambdaQueryWrapper<ImMessageDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImMessageDetail::getTarget, imMessageDetail.getTarget());
        queryWrapper.eq(ImMessageDetail::getType, imMessageDetail.getType());
        queryWrapper.eq(ImMessageDetail::getToUserId, imMessageDetail.getToUserId());
        queryWrapper.eq(ImMessageDetail::getTargetId, imMessageDetail.getTargetId());
        if (StringUtils.isNotBlank(imMessageDetail.getFromUserId())) {
            queryWrapper.eq(ImMessageDetail::getFromUserId, imMessageDetail.getFromUserId());
        }
        int i = this.baseMapper.updateImMessageStatus(queryWrapper);
        return i > 0 ? true : false;
    }

    @Override
    public List<ImMessageNumVo> findUnreadMessage() {
        return imMessageNumDao.findUnreadMessage(AuthenticationUtil.getUserId());
    }

    public List<ImSystemMessageFullVo> findSystemMessage() {
        LambdaQueryWrapper<ImMessageDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(ImMessageDetail::getToUserId, AuthenticationUtil.getUserId());
        return this.baseMapper.findSystemMessage(lambdaQueryWrapper);
    }
}
